using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LibVLCSharp.Shared;
using System;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows;
using VideoClient;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using System.Windows.Media.Imaging;
using System.IO;
// using System.Windows; // Removed duplicate

namespace vlcplay.ViewModels;

public partial class VideoItemViewModel : ObservableObject, IDisposable
{
    private readonly ILogger<VideoItemViewModel> logger = App.ServiceProvider.GetRequiredService<ILogger<VideoItemViewModel>>();

    private LibVLC _libvlc;
    private bool _isUserStop = false;
    private bool _isVideoViewLoaded = false;

    [ObservableProperty]
    private bool isPlaying;

    [ObservableProperty]
    private MediaPlayer? _mediaPlayer; // MediaPlayer can be initialized later

    [ObservableProperty]
    private string _videoUrl;

    [ObservableProperty]
    private string _statusText = "准备就绪";

    [ObservableProperty]
    private bool _isMaximized;

    public DevCh myDevCh;


    [ObservableProperty]
    private string _device;

    [ObservableProperty]
    private string _channel;

    [ObservableProperty]
    private string _name;
    public bool CanPlayVideo => !IsPlaying && !string.IsNullOrWhiteSpace(VideoUrl);
    public bool CanStopVideo => IsPlaying;

    partial void OnIsPlayingChanged(bool value)
    {
        PlayVideoCommand.NotifyCanExecuteChanged();
        StopVideoCommand.NotifyCanExecuteChanged();
    }

    [ObservableProperty]
    private string previewImagePath = "images/notfound.jpg";

    [ObservableProperty]
    private BitmapImage? previewImage;

    // Update constructor to accept device and channel
    public VideoItemViewModel(LibVLC libvlc, string url, DevCh devCh)
    {
        _libvlc = libvlc;
        _videoUrl = url;
        myDevCh = devCh;
        _device = devCh.Device;
        _channel = devCh.Channel;
        _name = devCh.Name;

        var client = App.ServiceProvider.GetService<XhVideoClient>();
        if (client != null)
        {
            // 订阅 PlayCode 刷新事件
            client.PlayCodeRefreshed += () => RefreshVideoUrl(client);

            // 1. 启动时优先加载本地图片
            var localPath = client.GetLocalSnapshotPath(devCh);
            LoadPreviewImage(localPath);

            // 2. 异步下载网络图片，下载完成后刷新
            _ = client.DownloadAndUpdateSnapshotAsync(myDevCh, () =>
            {
                Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    var newPath = client.GetLocalSnapshotPath(devCh);
                    LoadPreviewImage(newPath);
                });
            });
        }
    }

    // Add a public setter for IsVideoViewLoaded, or a new property for the maximized view's loaded state
    public void IsVideoViewLoaded_Set(bool value)
    {
        _isVideoViewLoaded = value;
    }

    public bool IsVideoViewLoaded
    {
        get => _isVideoViewLoaded;
        set
        {
            _isVideoViewLoaded = value;
            // 可以在这里自动播放（可选）
        }
    }


    public void EnsureMediaPlayer()
    {
        if (MediaPlayer == null)
        {
            MediaPlayer = new MediaPlayer(_libvlc);

            MediaPlayer.Playing += (s, e) =>
            {
                Application.Current.Dispatcher.BeginInvoke(() =>
                {
                    logger.LogInformation($"[MediaPlayer.Playing] {Device}_{Channel}");
                    StatusText = "正在播放...";
                    IsPlaying = true;
                    OnPropertyChanged(nameof(IsPlaying));
                });
            };
            MediaPlayer.Stopped += (s, e) =>
            {
                Application.Current.Dispatcher.BeginInvoke(() =>
                {
                    logger.LogInformation($"[MediaPlayer.Stopped] {Device}_{Channel}, UserStop: {_isUserStop}");
                    IsPlaying = false;
                    if (_isUserStop)
                        StatusText = "已停止";
                    OnPropertyChanged(nameof(IsPlaying));
                });
            };
            MediaPlayer.EncounteredError += (s, e) =>
            {
                Application.Current.Dispatcher.BeginInvoke(() =>
                {
                    logger.LogError($"[MediaPlayer.EncounteredError] {Device}_{Channel}");
                    IsPlaying = false;
                    StatusText = "播放错误！";
                    OnPropertyChanged(nameof(IsPlaying));
                });
            };
            MediaPlayer.EndReached += (s, e) =>
            {
                Application.Current.Dispatcher.BeginInvoke(() =>
                {
                    logger.LogInformation($"[MediaPlayer.EndReached] {Device}_{Channel}");
                    IsPlaying = false;
                    StatusText = "播放结束";
                    OnPropertyChanged(nameof(IsPlaying));
                });
            };
        }
    }
    public Task UpdatePreviewImageAsync(XhVideoClient client) // Changed to Task as it's not truly async
    {
        PreviewImagePath = client.GetLocalSnapshotPath(myDevCh);
        return Task.CompletedTask; // Return a completed task
    }


    [RelayCommand(CanExecute = nameof(CanPlayVideo))]
    private async Task PlayVideo()
    {
        logger.LogInformation($"[PlayVideo_Command] Triggered for {Device}_{Channel}. IsVideoViewLoaded: {IsVideoViewLoaded}");

        if (string.IsNullOrWhiteSpace(VideoUrl))
        {
            StatusText = "视频 URL 不能为空。";
            return;
        }

        int retry = 0;
        while (!IsVideoViewLoaded && retry < 10)
        {
            await Task.Delay(100);
            retry++;
        }

        // 将 IsPlaying 状态的更新提前，以便按钮状态能立即响应“尝试播放”的意图
        IsPlaying = true; 

        if (MediaPlayer == null)
        {
            StatusText = "播放器未就绪";
            IsPlaying = false; // 如果播放器未就绪，则重置 IsPlaying 状态
            return;
        }
        _isUserStop = false; 
        StatusText = "正在加载...";

        try
        {

            using var media = new Media(_libvlc, new Uri(VideoUrl));
            var result = MediaPlayer.Play(media);

            if (!result)
            {
                StatusText = $"播放失败，请检查 URL。";
                Debug.WriteLine($"Play failed for {VideoUrl}");
            }
            else
            {
                StatusText = $"尝试播放...";
            }
        }
        catch (UriFormatException)
        {
            StatusText = "无效的 URL 格式。";
            Debug.WriteLine($"Invalid URL format for {VideoUrl}");
        }
        catch (Exception ex)
        {
            StatusText = $"发生未知错误: {ex.Message}";
            Debug.WriteLine($"Error playing video {VideoUrl}: {ex.Message}");
        }
        logger.LogInformation($"[PlayVideo_Command] Ended for {Device}_{Channel}. MediaPlayer.IsPlaying: {MediaPlayer?.IsPlaying}");

    }


    [RelayCommand(CanExecute = nameof(CanStopVideo))]
    public void StopVideo()
    {
        logger.LogInformation($"[StopVideo_Command] Triggered for {Device}_{Channel}");
        if (MediaPlayer != null)
        {
            if (MediaPlayer.IsPlaying || MediaPlayer.State == VLCState.Opening || MediaPlayer.State == VLCState.Buffering)
            {
                _isUserStop = true;
                logger.LogInformation($"停止视频 {Device}_{Channel}，当前状态: {MediaPlayer.State}");
                MediaPlayer.Stop();
            }
            else
            {
                logger.LogInformation($"StopVideo 调用时 {Device}_{Channel} 未处于播放/打开/缓冲状态，当前状态: {MediaPlayer.State}");
            }
        }
    }

    public void DetachMediaPlayerFromView()
    {
        // 让小格子的 VideoView 释放 MediaPlayer
        if (IsMaximized)
            return;
        // 你可以通过事件或回调让小格子的 VideoView.MediaPlayer = null
        // 或者在小格子 VideoView 的 Unloaded 事件里自动置 null
    }

    public void Dispose()
    {
        MediaPlayer?.Stop();
        MediaPlayer?.Dispose();
        MediaPlayer = null;
        Debug.WriteLine($"视频项 {VideoUrl} 的 MediaPlayer 资源已释放。");
    }

    public void LoadPreviewImage(string path)
    {
        try
        {
            if (!File.Exists(path) || new FileInfo(path).Length < 100)
            {
                SetPreviewImageToDefault();
                return;
            }
            logger.LogInformation($"加载预览图: {path}");

            // 必须在UI线程创建BitmapImage
            if (!Application.Current.Dispatcher.CheckAccess())
            {
                Application.Current.Dispatcher.Invoke(() => LoadPreviewImage(path));
                return;
            }

            byte[] imageBytes = File.ReadAllBytes(path);
            BitmapImage bitmap = new BitmapImage();
            using (var ms = new MemoryStream(imageBytes))
            {
                bitmap.BeginInit();
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                bitmap.StreamSource = ms;
                bitmap.EndInit();
                bitmap.Freeze();
            }
            PreviewImage = bitmap;
        }        
        catch (Exception ex)
        {
            SetPreviewImageToDefault();
            logger.LogWarning($"{path} catch null: {ex.Message}");
        }
    }

    private void SetPreviewImageToDefault()
    {
        try
        {
            var defaultPath = "images/notfound.jpg";
            if (File.Exists(defaultPath))
            {
                var bitmap = new BitmapImage();
                using (var stream = new FileStream(defaultPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    bitmap.BeginInit();
                    bitmap.CacheOption = BitmapCacheOption.OnLoad;
                    bitmap.UriSource = null;
                    bitmap.StreamSource = stream;
                    bitmap.EndInit();
                    bitmap.Freeze();
                }
                if (!Application.Current.Dispatcher.CheckAccess())
                {
                    Application.Current.Dispatcher.Invoke(() => PreviewImage = bitmap); // bitmap can be null if defaultPath doesn't exist
                }
                else
                {
                    PreviewImage = bitmap;
                }
            }
            else
            {
                PreviewImage = null;
            }
        }
        catch
        {
            PreviewImage = null;
        }
    }

    public void RefreshVideoUrl(XhVideoClient client)
    {
        // 假设你的播放地址需要用到 PlayCode
        VideoUrl = $"rtmp://47.108.206.80:80/rtp/{Device}/{Channel}?code={client.PlayCode}";
        logger.LogInformation($"VideoUrl: {VideoUrl}");
    }
}
